package cn.biplam.back.services.operator;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import cn.biplam.common.client.DataFilter;
import cn.biplam.common.client.DbResource;
import cn.biplam.common.client.Operator;
import cn.biplam.common.client.OperatorExchange;
import cn.biplam.common.client.OperatorResult;
import cn.biplam.common.interfaces.OperatorServer;
import cn.biplam.common.paramters.PersisParam;
import cn.biplam.common.paramters.PersisParam.Cache_Type;
import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.ErrorMessage;

/**
 * 数据访问服务接口实现
 * @author WangSong 2009-6-2下午04:28:04
 * @version 1.0
 */
public class OperatorServerImpl  extends UnicastRemoteObject implements OperatorServer {

	private static final long serialVersionUID = 2305539509730384715L;
	private Lock mLock=new ReentrantLock();
	private int iCount=0;
	
	public OperatorServerImpl() throws RemoteException {
		iCount++;
	}
	
	/**
	 * 返回数据访问结果
	 * @param opId    持久化id
	 * @param userId  用户id
	 * @param filter  过滤器对象
	 */
	public OperatorResult get(String opId, String userId,
				DataFilter filter) throws RemoteException, ErrorMessage {
		return this.get(opId, userId, filter,null);
	}

	
	/**
	 * 返回数据访问结果
	 * @param opId    持久化id
	 * @param userId  用户id
	 * @param filter  过滤器对象
	 * @param dbResource 数据源
	 */
	public OperatorResult get(String opId, String userId,
				DataFilter filter, DbResource dbResource)
				throws RemoteException, ErrorMessage {
		return this.get(opId, userId, filter,dbResource,null,null);
	}	
	
	/**
	 * 取持久化对象
	 * @param userId 用户id
	 * @param cid  容器id
	 * @param filter 过滤器
	 * @param mDbResource 数据源信息
	 * @param pageId 页面id
	 * @param cacheType 是否刷新持久层（从数据库取数据，刷新持久层） refresh:刷新 lazy:不刷新
	 * @return Object
	 * @throws RemoteException
	 */
	public OperatorResult get(String opId,
			                  String userId,DataFilter filter,
			                  DbResource dbResource,
			                  String pageId,
			                  Cache_Type cacheType) throws RemoteException, ErrorMessage {
		try{
			this.addCount();
			if(cacheType==null)
				return OperatorExchange.get(opId, userId, filter, dbResource);
			else{
				return getFromPersist(userId, opId, filter,dbResource,pageId ,cacheType);
			}
		}catch(ErrorMessage e){
			throw e;
		}catch(Exception e){
			throw new ErrorMessage(e,"OperatorServer get failed:"+opId);
		}finally{
			this.reduceCount();
		}
	}
	
	/**
	 * 取持久化对象
	 * @param userId 用户id
	 * @param cid  容器id
	 * @param filter 过滤器
	 * @param mDbResource 数据源信息
	 * @param sqls sql语句
	 * @return OperatorResult
	 * @throws RemoteException
	 */
	public OperatorResult get(String opId,String userId,DataFilter filter,DbResource mDbResource,ArrayList<String> sqls) 
	                            throws RemoteException,ErrorMessage{
		if(filter == null){
			filter = new DataFilter();
		}
		filter.setSqls(sqls);
		if(mDbResource==null){
			mDbResource=new DbResource(DbResource.RT);
		}
		return OperatorExchange.get(opId, userId, filter, mDbResource);
	}
	
	/**
	 * 取持久化对象
	 * @param userId 用户id
	 * @param cid  容器id
	 * @param filter 过滤器
	 * @param mDbResource 数据源信息
	 * @param ifgetsql true:返回sql,不执行 false:执行不返回sql
	 * @return OperatorResult
	 * @throws RemoteException
	 */
	public OperatorResult get(String opId,String userId,DataFilter filter,DbResource mDbResource,boolean ifgetsql) 
	                            throws RemoteException,ErrorMessage{
		if(filter == null){
			filter = new DataFilter();
		}
		filter.setIfGetSql(ifgetsql);
		if(mDbResource==null){
			mDbResource=new DbResource(DbResource.RT);
		}
		return OperatorExchange.get(opId, userId, filter, mDbResource);
	}
	
	
	
	/**
	 * 取下一页信息
	 * @param opId      持久化id
	 * @param userId    用户id
	 * @param filter    过滤器
	 * @param pageNum   页码
	 * @return
	 * @throws ErrorMessage 
	 * @throws RemoteException 
	 */
	public OperatorResult getPage(String opId, 
									  String userId,
									  DataFilter filter) throws RemoteException, ErrorMessage{
		return this.get(opId, userId, filter);
	}
	
	/**
	 * 取下一页信息
	 * @param opId      持久化id
	 * @param userId    用户id
	 * @param filter    过滤器
	 * @param pageNum   页码
	 * @param showPageLine 每页显示条数
	 * @return
	 * @throws ErrorMessage 
	 * @throws RemoteException 
	 */
	public OperatorResult getPage(String opId, 
									  String userId,
									  DataFilter filter,
									  int showPageLine) throws RemoteException, ErrorMessage{
		if(filter == null){
			filter = new DataFilter();
		}
		filter.put("showPageLine", TOOLS.intToString(showPageLine));
		return this.get(opId, userId, filter);
	}
	
	/**
	 * 设置持久化对象
	 * @param userId 用户id
	 * @param pageId 页面id
	 * @param optId  操作id
	 * @param object 持久化对象
	 * @throws ErrorMessage 
	 */
	public void set(String userId,String pageId,String optId,Object object) throws RemoteException,ErrorMessage{
		PersisParam.set(userId,pageId, getOperaotrSub(optId), object);
	}
	
	/**
	 * 设置持久化对象
	 * @param userId 用户id
	 * @param pageId 页面id
	 * @param optId  操作id
	 * @param persisId 持久化id
	 * @param object 持久化对象
	 * @throws ErrorMessage 
	 */
	public void set(String userId,String pageId,String optId,String persisId,Object object) throws RemoteException,ErrorMessage{
		PersisParam.set(userId,pageId, getOperaotrSub(optId),persisId, object);
	}
	
	/**
	 * 从持久层取数据，先判断持久层是否为空，如果为空，
	 *      则先初始化数据到持久层，然后从持久层取数据
	 * @param userId 用户id
	 * @param operatorId  操作id
	 * @param filter 过滤器
	 * @param dbResource 数据源信息
	 * @param pageId 页面id
	 * @param cacheType 缓存类型
	 * @return OperatorResult
	 * @throws ErrorMessage
	 */
	private OperatorResult getFromPersist(String userId,
										  String operatorId,
										  DataFilter filter,
										  DbResource dbResource,
										  String pageId,
										  Cache_Type cacheType) throws ErrorMessage{
		if(filter == null){
			filter = new DataFilter();
		}
		if(Cache_Type.Refresh.equals(cacheType)){
			PersisParam.clear(userId, pageId);
			setPersist(userId, operatorId, filter, pageId,dbResource);
		}
		if(filter.getValue(Operator.persisId)!=null){
			if(PersisParam.get(userId,pageId, getOperaotrSub(operatorId),filter.getValue(Operator.persisId))==null){
				setPersist(userId, operatorId, filter,pageId ,dbResource);
			}
		}else{
			if(PersisParam.get(userId,pageId, getOperaotrSub(operatorId))==null){
				setPersist(userId, operatorId, filter,pageId ,dbResource);
			}
		}
		if(PersisParam.get(userId,pageId, getOperaotrSub(operatorId))!=null){
			if(filter.getValue(Operator.persisId)!=null){
				return (OperatorResult)PersisParam.get(userId,pageId, getOperaotrSub(operatorId),filter.getValue(Operator.persisId));
			}else{
				Object result = PersisParam.get(userId,pageId, getOperaotrSub(operatorId));
				if(result instanceof OperatorResult){
					return (OperatorResult)result;
				}else{
					return new OperatorResult();
				}
			}
		}
		return null;
	}
	
	/**
	 * 设置持久化对象
	 * @param userId    用户id
	 * @param operatorId  操作id
	 * @param filter  过滤器
	 * @param dbResource 数据源
	 * @throws ErrorMessage
	 */
	private void setPersist(String userId,
							String operatorId,
							DataFilter filter,
							String pageId,
							DbResource dbResource) throws ErrorMessage{
		if(filter == null){
			filter = new DataFilter();
		}
		if(filter.getValue(Operator.persisId)!=null){
			PersisParam.set(userId, 
					pageId,
					getOperaotrSub(operatorId),
			        filter.getValue(Operator.persisId),
			        OperatorExchange.get(operatorId, userId, filter, dbResource));
		}else{
			PersisParam.set(userId, 
							pageId,
							getOperaotrSub(operatorId),  
					        OperatorExchange.get(operatorId, userId, filter, dbResource));
		}
	}
	
	/**
	 * operatorId截位作为
	 * @param operatorId
	 * @return
	 */
	private String getOperaotrSub(String operatorId){
		return operatorId.substring(0,operatorId.length()-2);
	}
	
	/**服务的使用情况监控*/
	public int getCount() throws RemoteException {
		return this.iCount;
	}

	private synchronized void addCount() {
		this.iCount++;
	}

	private synchronized void reduceCount() {
		this.iCount--;
	}

	public void lock() throws RemoteException {
		mLock.lock();
	}

	public boolean trylock() throws RemoteException {
		return mLock.tryLock();
	}

	public void unlock() {
		mLock.unlock();
	}
}